package com.example.spring_blog.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtParserBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Slf4j
public class JwtUtils {
    // 过期毫秒时长 24小时
    public static final long expiration = 24 * 60 * 60 * 1000;
    // 密钥
    private static final String secretString="dVnsmy+SIX6pNptQdeclDSJ26EMSPEIhvZYKBTTug4k=";
    // 生成安全密钥
    private static final SecretKey secretKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString));


    /**
     * 生成token
     * @param claim
     * @return
     */
    public static String genJwt(Map<String, Object> claim) {
        String jwt = Jwts.builder()// 创建 JWT 构建器。
                .setClaims(claim)// 设置载荷
                .signWith(secretKey)// 使用密钥签名
                .setIssuedAt(new Date())// 设置签发时间
                // 设置过期时间
                .setExpiration(new Date(System.currentTimeMillis()+expiration))
                .compact();// 生成最终字符串
        System.out.println(jwt);
        return jwt;
    }

    /**
     * 验证token
     * @param jwt
     * @return
     */
    public static Claims parseJwt(String jwt) {
        // 验证令牌是否为空
        if (!StringUtils.hasLength(jwt)) {
            return null;
        }

        //创建解析器, 设置签名密钥
        JwtParserBuilder jwtParserBuilder =
                Jwts.parserBuilder().setSigningKey(secretKey);
        Claims claims = null;
        try {
            //解析token
            claims = jwtParserBuilder.build().parseClaimsJws(jwt).getBody();
        } catch (Exception e) {
            log.error("解析令牌错误，jwt:{}", jwt);
        }
        return claims;
    }

    /**
     * 从token中获取用户id
     * @param jwt
     * @return
     */
    public static Integer getUserIdFromToken(String jwt) {
        Claims claims = JwtUtils.parseJwt(jwt);
        if (claims != null) {
            Map<String, Object> userInfo = new HashMap<>(claims);
            return (Integer) userInfo.get("id");
        }
        return null;
    }
}
